package cn.fintecher.pangolin.service.report.service;

import cn.fintecher.pangolin.common.enums.BaseSelect;
import cn.fintecher.pangolin.common.enums.PayCheckStatus;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.PaymentRecord;
import cn.fintecher.pangolin.entity.mysql.PaymentCheck;
import cn.fintecher.pangolin.entity.mysql.QPaymentCheck;
import cn.fintecher.pangolin.service.report.elastic.PaymentRecordElastic;
import cn.fintecher.pangolin.service.report.model.PrincipalPaymentModel;
import cn.fintecher.pangolin.service.report.model.StarUserModel;
import cn.fintecher.pangolin.service.report.repository.PaymentCheckRepository;
import cn.fintecher.pangolin.service.report.response.PrincipalResponse;
import cn.fintecher.pangolin.service.report.response.StarUserResponse;
import com.querydsl.core.BooleanBuilder;
import org.apache.commons.collections4.IterableUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 17:24 2019/12/12
 */

@Service("homePageService")
public class HomePageService {
    @Autowired
    private PaymentRecordElastic paymentRecordElastic;

    @Autowired
    private PaymentCheckRepository paymentCheckRepository;

    /**
     * 委托方回款统计
     */
    public PrincipalResponse getPrincipal() {
        PrincipalResponse response = new PrincipalResponse();
        DateTime dateTime = new DateTime();
        BoolQueryBuilder builder1 = generateBuilder(dateTime.minusMonths(1).dayOfMonth().withMinimumValue().toDate(), dateTime.minusMonths(1).dayOfMonth().withMaximumValue().toDate());
        Iterable<PaymentRecord> lastIterable = paymentRecordElastic.search(builder1);
        dateTime = new DateTime();
        BoolQueryBuilder builder2 = generateBuilder(dateTime.dayOfMonth().withMinimumValue().toDate(), ZWDateUtil.getNowDateTime());
        Iterable<PaymentRecord> currentIterable = paymentRecordElastic.search(builder2);
        List<PaymentRecord> lastPaymentRecords = IterableUtils.toList(lastIterable);
        List<PaymentRecord> currentPaymentRecords = IterableUtils.toList(currentIterable);
        if (lastPaymentRecords.isEmpty()) {
            response.setLastPrincipalName("无");
            response.setLastPayment(0d);
        } else {
            Map<String, List<PaymentRecord>> map = lastPaymentRecords.stream().collect(Collectors.groupingBy(PaymentRecord::getPrincipalId));
            PrincipalPaymentModel model = calculatePayment(map);
            response.setLastPrincipalName(model.getPrincipalName());
            response.setLastPayment(model.getPaymentAmt());
        }
        if (currentPaymentRecords.isEmpty()) {
            response.setCurrentPrincipalName("无");
            response.setCurrentPayment(0d);
        } else {
            Map<String, List<PaymentRecord>> map = currentPaymentRecords.stream().collect(Collectors.groupingBy(PaymentRecord::getPrincipalId));
            PrincipalPaymentModel model = calculatePayment(map);
            response.setCurrentPrincipalName(model.getPrincipalName());
            response.setCurrentPayment(model.getPaymentAmt());
        }
        return response;
    }

    /**
     * 生成查询条件
     */
    private BoolQueryBuilder generateBuilder(Date startDate, Date endDate) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("flag", 0));
        builder.must(QueryBuilders.rangeQuery("operateTime").gte(startDate.getTime()));
        builder.must(QueryBuilders.rangeQuery("operateTime").lte(endDate.getTime() + 86400000));
        return builder;
    }

    /**
     * 计算回款金额
     */
    private PrincipalPaymentModel calculatePayment(Map<String, List<PaymentRecord>> map) {
        PrincipalPaymentModel model = new PrincipalPaymentModel();
        Double amt = 0d;
        String principalName = "无";
        for (Map.Entry<String, List<PaymentRecord>> entry : map.entrySet()) {
            List<PaymentRecord> list = entry.getValue();
            Double sum = list.stream().mapToDouble(PaymentRecord::getPaymentAmt).sum();
            if (sum > amt) {
                amt = sum;
                principalName = list.get(0).getPrincipalName();
            }
        }
        model.setPrincipalName(principalName);
        model.setPaymentAmt(amt);
        return model;
    }

    /**
     * 明星催收员统计
     */
    public StarUserResponse getStarUser() {
        StarUserResponse response = new StarUserResponse();
        DateTime dateTime = new DateTime();
        BooleanBuilder builder1 = generateBooleanBuilder(dateTime.minusMonths(1).dayOfMonth().withMinimumValue().toDate(), dateTime.minusMonths(1).dayOfMonth().withMaximumValue().toDate());
        Iterable<PaymentCheck> lastIterable = paymentCheckRepository.findAll(builder1);
        BooleanBuilder builder2 = generateBooleanBuilder(dateTime.dayOfMonth().withMinimumValue().toDate(), ZWDateUtil.getNowDateTime());
        Iterable<PaymentCheck> currentIterable = paymentCheckRepository.findAll(builder2);
        List<PaymentCheck> lastPaymentChecks = IterableUtils.toList(lastIterable);
        List<PaymentCheck> currentPaymentCheck = IterableUtils.toList(currentIterable);
        if (lastPaymentChecks.isEmpty()) {
            response.setLastStarUser("无");
            response.setLastPayment(0d);
        } else {
            Map<String, List<PaymentCheck>> map = lastPaymentChecks.stream().collect(Collectors.groupingBy(PaymentCheck::getApplyId));
            StarUserModel model = calculateUserPayment(map);
            response.setLastStarUser(model.getUserName());
            response.setLastPayment(model.getPayment());
        }
        if (currentPaymentCheck.isEmpty()) {
            response.setCurrentStarUser("无");
            response.setCurrentPayment(0d);
        } else {
            Map<String, List<PaymentCheck>> map = currentPaymentCheck.stream().collect(Collectors.groupingBy(PaymentCheck::getApplyId));
            StarUserModel model = calculateUserPayment(map);
            response.setCurrentStarUser(model.getUserName());
            response.setCurrentPayment(model.getPayment());
        }
        return response;
    }

    /**
     * 生成查询条件
     */
    private BooleanBuilder generateBooleanBuilder(Date startDate, Date endDate) {
        BooleanBuilder builder = new BooleanBuilder();
        QPaymentCheck qPaymentCheck = QPaymentCheck.paymentCheck;
        builder.and(qPaymentCheck.payCheckStatus.eq(PayCheckStatus.CP)).and(qPaymentCheck.isReply.eq(BaseSelect.YES));
        builder.and(qPaymentCheck.hasPaymentDate.goe(startDate)).and(qPaymentCheck.hasPaymentDate.loe(endDate));
        return builder;
    }

    /**
     * 计算回款金额
     */
    private StarUserModel calculateUserPayment(Map<String, List<PaymentCheck>> map) {
        StarUserModel model = new StarUserModel();
        Double amt = 0d;
        String userName = "无";
        for (Map.Entry<String, List<PaymentCheck>> entry : map.entrySet()) {
            List<PaymentCheck> list = entry.getValue();
            Double sum = list.stream().mapToDouble(PaymentCheck::getHasPaymentAmt).sum();
            if (sum > amt) {
                amt = sum;
                userName = list.get(0).getApplyName();
            }
        }
        model.setUserName(userName);
        model.setPayment(amt);
        return model;
    }
}
